package com.yeskery.nut.extend.responsive;

import com.yeskery.nut.application.ApplicationType;
import com.yeskery.nut.application.NutConfigure;
import com.yeskery.nut.core.AutoDetector;
import com.yeskery.nut.core.AutoDetectorProvider;
import com.yeskery.nut.core.BaseClassNameOnAutoDetector;
import com.yeskery.nut.core.MultiCondition;
import com.yeskery.nut.extend.responsive.convert.FastJson2ResponsiveConvert;
import com.yeskery.nut.extend.responsive.convert.FastJsonResponsiveConvert;
import com.yeskery.nut.extend.responsive.convert.JacksonJsonResponsiveConvert;
import com.yeskery.nut.plugin.PluginManager;

/**
 * json响应式插件的自动探测器提供器
 * @author sprout
 * 2022-07-01 17:36
 */
public class JsonResponsivePluginAutoDetectorProvider implements AutoDetectorProvider {

    /** Jackson json class名称 */
    private static final String JACKSON_JSON_CLASS_NAME = "com.fasterxml.jackson.databind.ObjectMapper";

    /** Fastjson2 class名称 */
    private static final String FASTJSON2_JSON_CLASS_NAME = "com.alibaba.fastjson2.JSON";

    /** Fastjson class名称 */
    private static final String FASTJSON_JSON_CLASS_NAME = "com.alibaba.fastjson.JSON";

    /** Jackson xml class名称 */
    private static final String JACKSON_XML_CLASS_NAME = "com.fasterxml.jackson.dataformat.xml.XmlMapper";

    /** 插件管理器 */
    private final PluginManager pluginManager;

    /** Nut 相关配置接口 */
    private final NutConfigure nutConfigure;

    /** 已经配置 */
    private boolean configured = false;

    /**
     * 构建json响应式插件的自动探测器
     * @param nutConfigure Nut相关配置接口
     */
    public JsonResponsivePluginAutoDetectorProvider(NutConfigure nutConfigure) {
        this.nutConfigure = nutConfigure;
        this.pluginManager = nutConfigure.getPluginManager();
    }

    @Override
    public AutoDetector[] getAutoDetectors() {
        return new AutoDetector[]{new JacksonJsonResponsiveAutoDetector(), new FastJson2ResponsiveAutoDetector(),
                new FastJsonResponsiveAutoDetector()};
    }

    /**
     * 是否支持当前应用类型
     * @param applicationType 应用类型
     * @return 是否支持当前应用类型
     */
    private boolean isSupport(ApplicationType applicationType) {
        return true;
    }

    /**
     * Jackson json响应式自动探测器
     * @author sprout
     * 2022-09-14 15:27
     */
    private class JacksonJsonResponsiveAutoDetector extends BaseClassNameOnAutoDetector {

        @Override
        public boolean isSupport(ApplicationType applicationType) {
            return JsonResponsivePluginAutoDetectorProvider.this.isSupport(applicationType);
        }

        @Override
        protected void completeDetect() {
            if (nutConfigure.getBasePackages().isEmpty()) {
                return;
            }
            if (!configured) {
                pluginManager.registerPlugin(new JsonResponsivePlugin(new JacksonJsonResponsiveConvert()));
                configured = true;
            }
        }

        @Override
        protected MultiCondition getMultiCondition() {
            return MultiCondition.ANY;
        }

        @Override
        protected String[] getMultiResources() {
            return new String[]{JACKSON_JSON_CLASS_NAME};
        }
    }

    /**
     * Fastjson2响应式自动探测器
     * @author sprout
     * 2022-09-14 15:27
     */
    private class FastJson2ResponsiveAutoDetector extends BaseClassNameOnAutoDetector {

        @Override
        public boolean isSupport(ApplicationType applicationType) {
            return JsonResponsivePluginAutoDetectorProvider.this.isSupport(applicationType);
        }

        @Override
        protected void completeDetect() {
            if (nutConfigure.getBasePackages().isEmpty()) {
                return;
            }
            if (!configured) {
                pluginManager.registerPlugin(new JsonResponsivePlugin(new FastJson2ResponsiveConvert()));
                configured = true;
            }
        }

        @Override
        protected MultiCondition getMultiCondition() {
            return MultiCondition.ANY;
        }

        @Override
        protected String[] getMultiResources() {
            return new String[]{FASTJSON2_JSON_CLASS_NAME};
        }
    }

    /**
     * Fastjson响应式自动探测器
     * @author sprout
     * 2022-09-14 15:27
     */
    private class FastJsonResponsiveAutoDetector extends BaseClassNameOnAutoDetector {

        @Override
        public boolean isSupport(ApplicationType applicationType) {
            return JsonResponsivePluginAutoDetectorProvider.this.isSupport(applicationType);
        }

        @Override
        protected void completeDetect() {
            if (nutConfigure.getBasePackages().isEmpty()) {
                return;
            }
            if (!configured) {
                pluginManager.registerPlugin(new JsonResponsivePlugin(new FastJsonResponsiveConvert()));
                configured = true;
            }
        }

        @Override
        protected MultiCondition getMultiCondition() {
            return MultiCondition.ANY;
        }

        @Override
        protected String[] getMultiResources() {
            return new String[]{FASTJSON_JSON_CLASS_NAME};
        }
    }
}
